Skip to content

Name an entity's own columns before the ones it inherits - #16

Merged
peopleworks merged 2 commits into
mainfrom
fix/own-properties-first
Aug 14, 2026
Merged

Name an entity's own columns before the ones it inherits#16
peopleworks merged 2 commits into
mainfrom
fix/own-properties-first

Conversation

@peopleworks

Copy link
Copy Markdown
Owner

Follow-up to #15, found reviewing it.

What happens

Folding inherited properties gives every entity the columns it persists, in the order the class reads them — root down, base first. Two summaries then take the first few of that list, and on an application with a shared audit base the first few are the base's for every entity at once.

The agent context's entity table, measured on a base of six audit columns:

Invoice — notable properties
before #15 Number, IssuedOn, Total, Customer
after #15 CreatedBy, CreatedOn, ChangedBy, ChangedOn, RowVersion
this branch Number, IssuedOn, Total, Customer, CreatedBy

Not one of Invoice's own columns survived a five-slot window. Across a seven-entity fixture, six rows carried the identical five names — a table whose whole job is to tell entities apart, unable to. Customer kept one column by accident, because a required property outranks the rest.

The same eight-slot summary in the navigation section of the published documents had it too. One fix per reader, or the reader who gets missed keeps the defect.

Why the corpora in #15 could not have shown it

Corpus Folded properties
FeatureCenter.NET.XPO 151 over 146 entities ~1 each
MainDemo.NET.XPO 26 over 17 entities
private legacy LIMS 0 its shared base declares no columns

All three have thin bases. The shape that hurts is the one #13 named — an audit base wider than the entities under it — and no fixture had it. AuditedXpoSolution is that shape: six inherited columns against two or three own ones. It is kept apart from DeepXpoSolution, whose tests pin exact property lists on a base of one column; the inverted proportion is the whole point of the new one.

How it decides

InheritedFrom, added in #15 for a renderer that had not been written yet, is what the summaries sort by — own first, then the inherited ones in their existing ranking, filling whatever slots are left. OrderByDescending is a stable sort, so within each group the root-down order #15 established is preserved.

The fold itself is right and the full listings are unaffected: they still read root down, the way the class does. Only the two fixed-width summaries change, and only in which end of the list they spend their width on.

Deliberately out of scope: a [PersistentAlias] on a shared base now makes every descendant report calculated properties (XafDetailTools, HtmlExplainerGenerator). That is redundancy rather than loss — the alias does apply to the descendant — and it belongs with the editorial half of #14.

Verification

299 tests, 0 warnings. Three of the four new tests fail on main:

AnEntitysOwnColumnsSurviveAFixedWidthSummary   index 0: expected "Reference", got "CreatedBy"
RequiredColumnsStillOutrankTheRestOfTheEntitysOwn   index 1: expected "IssuedOn", got "CreatedBy"
TheNavigationSummaryNamesTheEntitysOwnColumnsFirstToo   StartsWith fails

The fourth, TheBaseItselfStillNamesItsOwnColumns, passes both before and after on purpose: it exists so nobody "fixes" this by hiding inherited properties, which would blank the base's own row — the same defect facing the other way.

🤖 Generated with Claude Code

peopleworks and others added 2 commits August 14, 2026 11:04
Folding inherited properties (#15) gives every entity the columns it persists,
in the order the class reads them -- root down, base first. Two summaries then
take the first few of that list, and on an application with a shared audit base
the first few are the base's for every entity at once.

The agent context's entity table, on a base of six audit columns:

    before          Invoice   Number, IssuedOn, Total, Customer
    after #15       Invoice   CreatedBy, CreatedOn, ChangedBy, ChangedOn, RowVersion
    now             Invoice   Number, IssuedOn, Total, Customer, CreatedBy

Not one of Invoice's own columns survived a five-slot window. Across a fixture
of seven entities, six rows carried the identical five names -- a table whose
whole job is to tell entities apart, unable to. Customer kept one column by
accident, because a required property outranks the rest.

The fold itself is right and the full listings are unaffected: they still read
root down, the way the class does. Only the summaries change, and only in
which end of the list they spend a fixed width on. InheritedFrom, added in #15
for a renderer that had not been written yet, is what they sort by -- own
first, then the inherited ones in their existing ranking, filling whatever
slots are left. Every row now names what makes it different before what it
shares.

The same eight-slot summary in the navigation section of the published
documents had it too. One fix per reader.

The corpora #15 was verified against could not have shown this: FeatureCenter
folds about one property per entity, MainDemo 26 over 17, and the 196-entity
legacy application 0 -- its shared base declares no columns. The shape that
hurts is the one the issue named, an audit base wider than the entities under
it, and no fixture had it. AuditedXpoSolution is that shape.

Found reviewing #15.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#15 landed without an entry, and it is the largest user-visible change in the
batch: every entity's property list is different. The release notes for 0.13.0
are assembled from [Unreleased], so an omission here is an omission there.

One bullet rather than two. The window where an entity's own columns fell out
of a five-slot summary existed only between the fold landing and this branch --
it was never released, and a changelog that documents it is describing a
version nobody can install.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant